import { _decorator, Button, Camera, clamp, color, Component, Event, EventKeyboard, EventTouch, input, Input, KeyCode, Label, Node, Slider, Sprite, SpriteFrame, toDegree, Tween, tween, UIOpacity, UITransform, v2, v3, Vec2, Vec3, view } from 'cc';
import { BoxPanelUI } from './BoxPanelUI';
import { EventName } from 'db://assets/Scripts/Framework/Const/EventName';
import { UIManager } from 'db://assets/Scripts/Framework/Managers/UIManager';
import Events from 'db://assets/Scripts/Framework/Utils/Events';
import { EasingType } from 'db://assets/Scripts/Framework/Utils/TweenUtil';
import { Ammo } from '../Items/Ammo';
import { Gun } from '../Items/Gun';
import { Heal } from '../Items/Heal';
import { Melee } from '../Items/Melee';
import { Weapon } from '../Items/Weapon';
import { InGameManager } from '../Managers/InGameManager';
import { PlayerController } from '../PlayerController';
import { PackUI } from './PackUI';
import { PoisonManager } from '../Managers/PoisonManager';
import { GameUI } from '../GameUI';
import { GamerController } from '../GamerController';
import { BundleManager } from 'db://assets/Scripts/Framework/Managers/BundleManager';
import { GameDataManager } from 'db://assets/MainPack/Scripts/GameDataManager';
const { ccclass, property } = _decorator;

@ccclass('ControlUI')
export class ControlUI extends Component {

    private static instance: ControlUI;
    public static get Instance(): ControlUI {
        return this.instance;
    }

    @property(Node)
    joyRect: Node;

    @property(Node)
    rotatePanel: Node;

    @property(Node)
    shoot: Node;

    @property(Node)
    HealItems: Node;

    @property(Node)
    healTimePanel: Node;

    @property(Node)
    armors: Node;

    @property(Node)
    frontSight: Node;

    @property(Node)
    sniperAim: Node;

    @property(Node)
    subWeapons: Node;

    @property(Node)
    box: Node;

    @property(Node)
    reload: Node;

    @property(Node)
    hurts: Node;

    @property(Node)
    poisonTime: Node;

    @property(Node)
    poison: Node;

    @property(Node)
    pack: Node;

    @property(Node)
    gamerLeft: Node;

    @property(Node)
    atk2: Node;

    @property(Node)
    parachuteBtn: Node;

    @property(Node)
    parachute: Node;

    @property(Node)
    btns: Node;

    @property(Node)
    bossStateBar: Node;

    @property(Node)
    boss: Node;

    @property(Sprite)
    aim: Sprite;

    @property(Sprite)
    hp: Sprite;

    @property(Sprite)
    bossHp: Sprite;

    @property(Sprite)
    YellowHp: Sprite;

    @property(Sprite)
    packLevel: Sprite;

    @property(Slider)
    autoShoot: Slider;

    @property(Label)
    autoLabel: Label;

    @property(Label)
    hpLabel: Label;

    @property(Camera)
    playerCamera: Camera;

    @property(BoxPanelUI)
    boxPanel: BoxPanelUI;

    @property([Node])
    weapons: Node[] = [];

    @property([Node])
    maps: Node[] = [];

    @property([SpriteFrame])
    atkSfs: SpriteFrame[] = [];

    @property([SpriteFrame])
    aimSfs: SpriteFrame[] = [];

    @property([SpriteFrame])
    levelSfs: SpriteFrame[] = [];

    @property([SpriteFrame])
    weaponBgSfs: SpriteFrame[] = [];

    @property([SpriteFrame])
    autoSfs: SpriteFrame[] = [];

    pastPos: Vec2 = null;
    delta: Vec3;
    outJoy: Node;
    lockJoy: Node;
    isAim = false;
    isShowHeal = false;
    isShowSub = false;
    isAuto = false;
    isSwitch = false;
    screenDistanceFactor: number = 1000;
    heals = [0, 0, 0, 0, 0];

    protected onLoad(): void {
        ControlUI.instance = this;
        // Events.once(EventName.JsonCompleted, this._Init, this);
    }

    start() {
        this.gamerLeft.children[1].getComponent(Label).string = `存活：${InGameManager.Instance.allGamers}`;
        this._PlayerEventInit();
        this._ControlInit();
        // PlayerController.Instance.animationController.setValue("IsParachute", true);
    }

    update(deltaTime: number) {
        this._CheckPoison();
        this._CheckBoss();
    }

    protected onDestroy(): void {
        Events.targetOff(this);
    }

    _Init() {
        this._CheckHeal();
        this._SubShow();
        this._CheckArmors();
        this._CheckAim();
        this._CheckReload();
    }

    _ControlInit() {
        input.on(Input.EventType.KEY_PRESSING, this._KeyProcess, this);
        input.on(Input.EventType.KEY_DOWN, this._KeyProcess, this);
        input.on(Input.EventType.KEY_UP, this._KeyEnd, this);
        this.joyRect.on(Node.EventType.TOUCH_START, this._PlayerTouchStart, this);
        this.joyRect.on(Node.EventType.TOUCH_MOVE, this._PlayerTouchMove, this);
        this.joyRect.on(Node.EventType.TOUCH_END, this._PlayerTouchEnd, this);
        this.joyRect.on(Node.EventType.TOUCH_CANCEL, this._PlayerTouchEnd, this);
        this.rotatePanel.on(Node.EventType.TOUCH_START, this._CameraTouchStart, this);
        this.rotatePanel.on(Node.EventType.TOUCH_MOVE, this._CameraTouchMove, this);
        this.shoot.on(Node.EventType.TOUCH_START, this._ShootStart, this);
        this.shoot.on(Node.EventType.TOUCH_MOVE, this._ShootMove, this);
        this.shoot.on(Node.EventType.TOUCH_END, this._ShootEnd, this);
        this.shoot.on(Node.EventType.TOUCH_CANCEL, this._ShootEnd, this);
        this.atk2.on(Node.EventType.TOUCH_START, this._ShootStart, this);
        this.atk2.on(Node.EventType.TOUCH_MOVE, this._ShootMove, this);
        this.atk2.on(Node.EventType.TOUCH_END, this._ShootEnd, this);
        this.atk2.on(Node.EventType.TOUCH_CANCEL, this._ShootEnd, this);
        this.outJoy = this.joyRect.children[0].children[1];
        this.lockJoy = this.joyRect.children[0].children[2];
    }

    _PlayerEventInit() {
        Events.on(EventName.PlayerHealStart, this._HealStart, this);
        Events.on(EventName.PlayerHealCheck, this._HealCheck, this);
        Events.on(EventName.PlayerHealCompleted, this._HealCompleted, this);
        Events.on(EventName.PlayerWeaponCheck, this._CheckWeapon, this);
        Events.on(EventName.PlayerHealUI, this._CheckHeal, this);
        Events.on(EventName.PlayerArmorCheck, this._CheckArmors, this);
        Events.on(EventName.PlayerWeaponData, this._CheckWeaponData, this);
        Events.on(EventName.PlayerShootCheck, this._CheckShoot, this);
        Events.on(EventName.PlayerPackLevel, this._CheckPackLevel, this);
        Events.on(EventName.PlayerFullPack, this._CheckFullPack, this);
        Events.on(EventName.PlayerBoxCheck, this._BoxInit, this);
        Events.on(EventName.PlayerHurt, this._Hurt, this);
        Events.on(EventName.PlayerKill, this._CheckKill, this);
        Events.on(EventName.GamerDie, this._CheckGamer, this);
    }

    _KeyProcess(event: EventKeyboard) {
        if (PlayerController.Instance.isDead) return;
        Tween.stopAllByTarget(PlayerController.Instance.deltaNor);
        const step = 1;
        switch (event.keyCode) {
            case KeyCode.KEY_W:
                PlayerController.Instance.deltaNor.y = 1;
                PlayerController.Instance.Control_z += step;
                break;
            case KeyCode.KEY_S:
                PlayerController.Instance.deltaNor.y = -1;
                PlayerController.Instance.Control_z -= step;
                break;
            case KeyCode.KEY_A:
                PlayerController.Instance.deltaNor.x = -1;
                PlayerController.Instance.Control_x -= step;
                break;
            case KeyCode.KEY_D:
                PlayerController.Instance.deltaNor.x = 1;
                PlayerController.Instance.Control_x += step;
                break;
            case KeyCode.KEY_R:
                this.Reload();
                break;
            case KeyCode.SPACE:
                this.Jump();
                break;
        }
        PlayerController.Instance.Control_z = clamp(PlayerController.Instance.Control_z, -1, 1);
        PlayerController.Instance.Control_x = clamp(PlayerController.Instance.Control_x, -1, 1);
    }

    _KeyEnd(event: EventKeyboard) {
        if (PlayerController.Instance.isDead) return;
        switch (event.keyCode) {
            case KeyCode.KEY_W:
            case KeyCode.KEY_S:
                tween(PlayerController.Instance.deltaNor)
                    .to(0.5, { y: 0 })
                    .start();
                PlayerController.Instance.Control_z = 0;
                break;
            case KeyCode.KEY_A:
            case KeyCode.KEY_D:
                tween(PlayerController.Instance.deltaNor)
                    .to(0.5, { x: 0 })
                    .start();
                PlayerController.Instance.Control_x = 0;
                break;
        }
    }

    _PlayerTouchStart(event: EventTouch) {
        if (PlayerController.Instance.isDead) return;
        var pos = event.getUILocation().toVec3();
        this.joyRect.children[0].setWorldPosition(pos);
        Tween.stopAllByTarget(PlayerController.Instance.deltaNor);
        this.outJoy.active = false;
        this.lockJoy.active = false;
        PlayerController.Instance.isRun = false;
    }

    _PlayerTouchMove(event: EventTouch) {
        if (PlayerController.Instance.isDead) return;
        var joy = this.joyRect.children[0].children[0];
        var pos = event.getUILocation().toVec3();
        var basePos = this.joyRect.children[0].getWorldPosition();
        var maxDis = this.joyRect.children[0].getComponent(UITransform).width / 2;
        var delta = v3(pos.x - basePos.x, pos.y - basePos.y, 0);
        let v = v3();
        Vec3.multiplyScalar(v, delta, 1 / maxDis);
        PlayerController.Instance.Control_x = v.x;
        PlayerController.Instance.Control_z = v.y;
        PlayerController.Instance.deltaNor.set(PlayerController.Instance.Control_x, PlayerController.Instance.Control_z);
        if (PlayerController.Instance.Control_z > 1) {
            PlayerController.Instance.Control_z = 1.5;
            this.outJoy.active = true;
            PlayerController.Instance.isRun = true;
        }
        else {
            this.outJoy.active = false;
            PlayerController.Instance.isRun = false;
        }
        if (delta.length() > maxDis) {
            delta = delta.normalize().multiplyScalar(maxDis);
            joy.setPosition(delta);
        }
        else joy.setWorldPosition(pos);
        this.delta = delta;
    }

    _PlayerTouchEnd(event: EventTouch) {
        if (PlayerController.Instance.isDead) return;
        if (!this.outJoy.active || !this.outJoy.children[2].getComponent(UITransform).getBoundingBoxToWorld().contains(event.getUILocation())) {
            tween(PlayerController.Instance.deltaNor)
                .to(0.5, { x: 0, y: 0 })
                .start();
            PlayerController.Instance.Control_x = 0;
            PlayerController.Instance.Control_z = 0;
            var joy = this.joyRect.children[0].children[0];
            joy.setPosition(Vec3.ZERO);
            this.joyRect.children[0].setPosition(Vec3.ZERO);
            this.outJoy.active = false;
            PlayerController.Instance.isRun = false;
        }
        else {
            PlayerController.Instance.Control_x = 0;
            PlayerController.Instance.Control_z = 1.5;
            PlayerController.Instance.deltaNor.set(PlayerController.Instance.Control_x, PlayerController.Instance.Control_z);
            var joy = this.joyRect.children[0].children[0];
            joy.setPosition(v3(0, 160));
            this.lockJoy.active = true;
            PlayerController.Instance.isRun = true;
        }
    }

    _CameraTouchStart(event: EventTouch) {
        if (PlayerController.Instance.isDead) return;
        this.pastPos = event.getUILocation();
    }

    _CameraTouchMove(event: EventTouch) {
        if (PlayerController.Instance.isDead) return;
        var delta = event.getUILocation().subtract(this.pastPos).multiplyScalar(0.1);
        let playerEuler = PlayerController.Instance.node.eulerAngles;
        var euler = v3(PlayerController.Instance.node.children[2].eulerAngles.x, playerEuler.y, 0);
        euler.add3f(delta.y, -delta.x, 0);
        euler.x = clamp(euler.x, -90, 90);
        PlayerController.Instance.node.setRotationFromEuler(v3(0, euler.y, 0));
        PlayerController.Instance.node.children[2].setRotationFromEuler(v3(euler.x, 0, 0));
        this.pastPos = event.getUILocation();
    }

    Jump() {
        if (PlayerController.Instance.isDead) return;
        PlayerController.Instance.Jump();
    }

    Reload() {
        if (PlayerController.Instance.isDead) return;
        PlayerController.Instance.TryReload();
    }

    _CheckReload() {
        let weapon = PlayerController.Instance.backPack.CurWeapon;
        this.reload.active = weapon instanceof Gun;
    }

    Aim() {
        if (PlayerController.Instance.isDead) return;
        this.isAim = !this.isAim;
        PlayerController.Instance.Aim(this.isAim);
        this.aim.spriteFrame = this.aimSfs[this.isAim ? 1 : 0];
        this._CheckAim();
    }

    _CheckAim() {
        Tween.stopAllByTarget(this.playerCamera);
        let num = 35;
        let weapon = PlayerController.Instance.backPack.CurWeapon;
        if (weapon instanceof Gun) {
            this.frontSight.active = !(weapon.type == 2 && this.isAim);
            this.pack.active = this.frontSight.active;
            this.sniperAim.active = weapon.type == 2 && this.isAim;
            this.playerCamera.visibility = weapon.type == 2 && this.isAim ? 1 << 3 | 1 << 30 : 1 << 3 | 1 << 30 | 1 << 5;
            if (weapon.modules[0]) num -= weapon.modules[0].figure;
        }
        else {
            this.frontSight.active = true;
            this.pack.active = true;
        }
        num = this.isAim ? num : 45;
        const screenHeight = view.getVisibleSize().height;
        this.screenDistanceFactor = screenHeight / (2 * Math.tan(num * Math.PI / 360));
        tween(this.playerCamera)
            .to(0.1, { fov: num })
            .start();
    }

    Box() {
        this.boxPanel.node.active = !this.boxPanel.node.active;
    }

    _BoxInit() {
        if (PlayerController.Instance.backPack.ContainBox) {
            this.box.active = true;
            this.boxPanel.Init();
        }
        else this.box.active = false;
        InGameManager.Instance.endData[2]++;
    }

    _ShootStart(event: EventTouch) {
        if (PlayerController.Instance.isDead) return;
        this._CameraTouchStart(event);
        PlayerController.Instance.ShootStart();
    }

    _ShootMove(event: EventTouch) {
        if (PlayerController.Instance.isDead) return;
        this._CameraTouchMove(event);
    }

    _ShootEnd() {
        if (PlayerController.Instance.isDead) return;
        PlayerController.Instance.ShootEnd();
    }

    WeaponChoose(event: Event) {
        if (this.isSwitch) return;
        if (PlayerController.Instance.animationController.getValue("IsChooseWeapon")) return;
        this.isSwitch = true;
        this.scheduleOnce(() => { this.isSwitch = false; }, 1);
        let target: Node = event.target;
        let weapon: Weapon;
        if (this.weapons.indexOf(target) != -1) {
            let num = this.weapons.indexOf(target);
            weapon = PlayerController.Instance.backPack.guns[num + 1];
        }
        else {
            let num = target.getSiblingIndex();
            if (num == 0) weapon = PlayerController.Instance.backPack.guns[0];
            else if (num == 1) weapon = PlayerController.Instance.backPack.melee;
        }
        if (weapon == PlayerController.Instance.backPack.CurWeapon) {
            if (weapon == null) return;
            weapon = null;
        }
        this._WeaponChoose(weapon);
    }

    _WeaponChoose(weapon: Weapon) {
        PlayerController.Instance.healItem = null;
        PlayerController.Instance.healTime = 0;
        PlayerController.Instance.isHeal = false;
        PlayerController.Instance.animationController.setValue("IsHeal", false);
        this._HealCompleted();
        PlayerController.Instance.WeaponSwitch(weapon);
    }

    _CheckWeaponData(ammo: Ammo);
    _CheckWeaponData(weapon: Weapon, isSwitch: boolean);
    _CheckWeaponData(arg: Weapon | Ammo | number, isSwitch = false) {
        let pack = PlayerController.Instance.backPack;
        if (arg instanceof Weapon) {
            let sprite: Sprite;
            let label: Label;
            let num = pack.guns.indexOf(arg as Gun);
            if (arg instanceof Gun) {
                if (num > 0) {
                    sprite = this.weapons[num - 1].children[0].getComponent(Sprite);
                    label = this.weapons[num - 1].children[1].getComponent(Label);
                }
                else {
                    sprite = this.subWeapons.children[0].children[0].getComponent(Sprite);
                    label = this.subWeapons.children[0].children[1].getComponent(Label);
                }
                if (label) {
                    let ammos = pack.items.filter((value, index, array) => { if (value instanceof Ammo && value.type == arg.type) return value; });
                    let ammo = 0;
                    ammos.forEach(element => { ammo += element.num; });
                    label.string = `${arg.curAmmo}/${ammo}`;
                }
            }
            else if (arg instanceof Melee) sprite = this.subWeapons.children[1].children[0].getComponent(Sprite);
            if (sprite && isSwitch) BundleManager.GetBundle("MainPack").load(num > 0 ? arg.weaponSfUrl : arg.sfUrl, SpriteFrame, (err, data) => { if (sprite.spriteFrame != data) sprite.spriteFrame = data });
            this._SubShow();
        }
        else if (arg instanceof Ammo) {
            let guns = pack.guns.filter((value, index, array) => { if (value && value.type == arg.type) return value; });
            if (guns.length > 0) {
                let ammos = pack.items.filter((value, index, array) => { if (value instanceof Ammo && value.type == arg.type) return value; });
                let ammo = 0;
                ammos.forEach(element => { ammo += element.num; });
                for (let i = 0; i < guns.length; i++) {
                    const element = guns[i];
                    const num = pack.guns.indexOf(element);
                    let sprite: Sprite;
                    let label: Label;
                    if (num > 0) {
                        sprite = this.weapons[num - 1].children[0].getComponent(Sprite);
                        label = this.weapons[num - 1].children[1].getComponent(Label);
                    }
                    else {
                        sprite = this.subWeapons.children[0].children[0].getComponent(Sprite);
                        label = this.subWeapons.children[0].children[1].getComponent(Label);
                    }
                    if (label) {
                        label.string = `${element.curAmmo}/${ammo}`;
                    }
                }
            }
        }
        else {
            let guns = pack.guns.filter((value, index, array) => { if (value && value.type == arg) return value; });
            if (guns.length > 0) {
                let ammos = pack.items.filter((value, index, array) => { if (value instanceof Ammo && value.type == arg) return value; });
                let ammo = 0;
                ammos.forEach(element => { ammo += element.num; });
                for (let i = 0; i < guns.length; i++) {
                    const element = guns[i];
                    const num = pack.guns.indexOf(element);
                    let sprite: Sprite;
                    let label: Label;
                    if (num > 0) {
                        sprite = this.weapons[num - 1].children[0].getComponent(Sprite);
                        label = this.weapons[num - 1].children[1].getComponent(Label);
                    }
                    else {
                        sprite = this.subWeapons.children[0].children[0].getComponent(Sprite);
                        label = this.subWeapons.children[0].children[1].getComponent(Label);
                    }
                    if (label) {
                        label.string = `${element.curAmmo}/${ammo}`;
                    }
                }
            }
        }
        this._CheckReload();
    }

    _CheckWeapon(weapon: Weapon) {
        this.weapons.forEach(element => { element.getComponent(Sprite).spriteFrame = this.weaponBgSfs[0]; });
        this.subWeapons.children.forEach(element => { if (this.subWeapons.children.indexOf(element) != 3) element.getComponent(Sprite).spriteFrame = this.weaponBgSfs[2]; });
        let num = 0;
        if (weapon) {
            if (weapon instanceof Gun) {
                num = 1;
                let num2 = PlayerController.Instance.backPack.guns.indexOf(weapon);
                if (num2 > 0) this.weapons[num2 - 1].getComponent(Sprite).spriteFrame = this.weaponBgSfs[1];
                else this.subWeapons.children[0].getComponent(Sprite).spriteFrame = this.weaponBgSfs[3];
            }
            else if (weapon instanceof Melee) {
                num = 2;
                this.subWeapons.children[1].getComponent(Sprite).spriteFrame = this.weaponBgSfs[3];
            }
        }
        this.shoot.getComponent(Sprite).spriteFrame = this.atkSfs[num];
        this.atk2.getComponent(Sprite).spriteFrame = this.atkSfs[num];
        PackUI.Instance.GunInit();
        if (this.isAim) this.Aim();
    }

    _DropWeapon(num: number) {
        let target: Node;
        if (num < 3) {
            target = this.weapons[num - 1];
            target.children[0].getComponent(Sprite).spriteFrame = null;
            target.children[1].getComponent(Label).string = "";
        }
        else {
            if (num == 0) target = this.subWeapons.children[0];
            else target = this.subWeapons.children[1];
            target.active = false;
            this._SubShow();
        }
    }

    ShowSub(event: Event) {
        this.isShowSub = !this.isShowSub;
        let target: Node = event.target;
        target.angle = this.isShowSub ? 0 : 180;
        this._SubShow();
    }

    _SubShow() {
        let isShow = false;
        let pack = PlayerController.Instance.backPack;
        if (pack.guns[0]) {
            this.subWeapons.children[0].active = true;
            isShow = true;
        }
        else this.subWeapons.children[0].active = false;
        this.subWeapons.children[1].active = ((this.isShowSub || !isShow) && pack.melee != null);
        this.subWeapons.children[2].active = !this.subWeapons.children[0].active && !this.subWeapons.children[1].active;
    }

    _CheckShoot() {
        let weapon = PlayerController.Instance.backPack.CurWeapon;
        if (weapon instanceof Gun) {
            let spread = PlayerController.Instance.curSpread;
            if (this.isAim) {
                let num = 35;
                if (weapon.modules[0]) num -= weapon.modules[0].figure;
                spread *= num / 45;
            }
            // 将散布角度转换为屏幕上的位移
            const spreadOffset = this.angleToScreenOffset(spread);
            this.frontSight.children[0].setPosition(v3(-spreadOffset, 0));
            this.frontSight.children[1].setPosition(v3(spreadOffset, 0));
            this.frontSight.children[2].setPosition(v3(0, spreadOffset));
            this.frontSight.children[3].setPosition(v3(0, -spreadOffset));
        }
        else {
            this.frontSight.children[0].setPosition(v3(-10, 0));
            this.frontSight.children[1].setPosition(v3(10, 0));
            this.frontSight.children[2].setPosition(v3(0, 10));
            this.frontSight.children[3].setPosition(v3(0, -10));
        }
    }

    // 将角度转换为屏幕上的位移
    angleToScreenOffset(angleInDegrees: number): number {
        // 使用简单的正切计算将角度转换为屏幕位移
        // 假设屏幕距离因子代表虚拟的"屏幕距离"
        const angleInRadians = angleInDegrees * Math.PI / 180;
        return Math.tan(angleInRadians) * this.screenDistanceFactor;
    }

    Pack() {

    }

    ShowHeal(event: Event) {
        this.isShowHeal = !this.isShowHeal;
        let target: Node = event.target;
        target.angle = this.isShowHeal ? 0 : 180;
        this._HealShow();
    }

    _CheckHeal() {
        let pack = PlayerController.Instance.backPack;
        this.heals = [];
        let data = InGameManager.itemsJson;
        for (let i = 0; i < data.Heal.length; i++) {
            const element = data.Heal[i].name;
            let item = pack.items.find((value, index, obj) => { if (value.itemName == element) return value; });
            if (item) this.heals.push(item.num);
            else this.heals.push(0);
        }
        let num = this.heals.find((value, index, obj) => { if (value > 0) return value });
        this.HealItems.children[this.HealItems.children.length - 2].active = num == undefined;
        this._HealShow();
    }

    _HealShow() {
        let isShow = false;
        for (let i = 0; i < this.HealItems.children.length - 2; i++) {
            const element = this.HealItems.children[i];
            element.active = (!isShow || this.isShowHeal) && this.heals[i] > 0;
            if (element.active) isShow = true;
            element.children[1].getComponent(Label).string = this.heals[i].toString();
        }
    }

    UseHeal(event: Event) {
        let target: Node = event.target;
        let num = target.getSiblingIndex();
        let data = InGameManager.itemsJson;
        let itemName = data.Heal[num].name;
        let pack = PlayerController.Instance.backPack;
        let heal = pack.items.find((value, index, obj) => { if (value.itemName == itemName) return value; }) as Heal;
        if (!heal) return;
        if (heal.num == 0) return;
        if (PlayerController.Instance.Hp == 100) return;
        this._UseHeal(heal);
    }

    _UseHeal(heal: Heal) {
        PlayerController.Instance.healItem = heal;
        PlayerController.Instance.healTime = heal.time;
        PlayerController.Instance.Heal();
    }

    _HealStart() { this.healTimePanel.active = true; }

    _HealCheck() {
        let num = PlayerController.Instance.healTime.toFixed(1);
        this.healTimePanel.children[0].getComponent(Sprite).fillRange = PlayerController.Instance.healTime / PlayerController.Instance.healItem.time;
        this.healTimePanel.children[1].getComponent(Label).string = num;
    }

    _HealCompleted() {
        this.healTimePanel.active = false;
        this._CheckHeal();
    }

    _HpChange() {
        if (GameUI.Instance.isFinish) return;
        let c = 255 * PlayerController.Instance.hp / 100;
        this.hp.color.set(color(255, c, c));
        let num = Math.ceil(PlayerController.Instance.hp);
        this.hpLabel.string = `${num.toFixed()} / 100`;
        this.unschedule(this._YellowHpChange);
        if (this.YellowHp.fillRange > this.hp.fillRange) this._YellowHpChange();
        else this.YellowHp.fillRange = this.hp.fillRange;
    }

    _YellowHpChange() {
        Tween.stopAllByTarget(this.YellowHp);
        tween(this.YellowHp)
            .to(1, { fillRange: this.hp.fillRange }, { easing: EasingType.circOut })
            .start();
    }

    _CheckArmors() {
        let pack = PlayerController.Instance.backPack;
        let Armors = pack.armors;
        if (Armors.length == 0) {
            for (let i = 0; i < this.armors.children.length; i++) {
                const element = this.armors.children[i];
                element.active = false;
            }
        }
        else {
            for (let i = 0; i < Armors.length; i++) {
                const element = Armors[i];
                this.armors.children[i == 0 ? 1 : 0].active = element != null;
                if (!element) continue;
                this.armors.children[i == 0 ? 1 : 0].children[1].getComponent(Sprite).fillRange = 1 - (element.durability / element.maxDurability);
                this.armors.children[i == 0 ? 1 : 0].children[2].getComponent(Sprite).spriteFrame = this.levelSfs[element.level];
            }
        }
    }

    _CheckPackLevel() {
        let pack = PlayerController.Instance.backPack.pack;
        let num = pack ? pack.level - 1 : -1;
        this.packLevel.spriteFrame = this.levelSfs[num];
    }

    _CheckFullPack() {
        UIManager.ShowTip("背包已满！");
    }

    OpenPack() {
        PackUI.Instance.OpenPack();
    }

    _Hurt(source: GamerController) {
        let pos = v3();
        Vec3.subtract(pos, source.node.getWorldPosition(), PlayerController.Instance.node.getWorldPosition());
        let sPos = v2(pos.x, pos.z);
        let playerPos = PlayerController.Instance.node.forward;
        let pPos = v2(playerPos.x, playerPos.z);
        let degree = toDegree(sPos.signAngle(pPos));
        let hurt = this.hurts.children[0];
        if (degree > 45 && degree <= 135) hurt = this.hurts.children[1];
        else if (degree > 135 || degree < -135) hurt = this.hurts.children[2];
        else if (degree < -45 && degree >= -135) hurt = this.hurts.children[3];
        hurt.getComponent(UIOpacity).opacity = 255;
        Tween.stopAllByTarget(hurt.getComponent(UIOpacity));
        tween(hurt.getComponent(UIOpacity))
            .to(2, { opacity: 0 }, { easing: EasingType.circOut })
            .start();
    }

    _Hit() {
        let hit = this.frontSight.children[4].getComponent(UIOpacity);
        hit.opacity = 255;
        Tween.stopAllByTarget(hit);
        tween(hit).to(0.2, { opacity: 0 }).start();
    }

    SwitchMaps() {
        this.maps[0].active = !this.maps[0].active;
        this.maps[1].active = !this.maps[1].active;
    }

    _CheckBoss() {
        if (this.bossStateBar.active) {
            let pos = this.boss.getWorldPosition().add3f(0, 10, 0);
            let num = (400 - Math.min(Vec3.distance(pos, this.playerCamera.node.getWorldPosition()), 400)) / 200;
            this.bossStateBar.setScale(Vec3.ONE.clone().multiplyScalar(num));
            this.playerCamera.convertToUINode(pos, this.node, pos);
            this.bossStateBar.setPosition(pos);
        }
    }

    _CheckPoison() {
        let sprite = this.poisonTime.children[0].getComponent(Sprite);
        sprite.fillRange = 1 - PoisonManager.Instance.time / 90;
        let label = this.poisonTime.children[1].getComponent(Label);
        label.string = PoisonManager.Instance.time == 0 ? `安全区正在缩小！` : `距离下次缩圈还有${Math.floor(PoisonManager.Instance.time)}秒`;
        this.poison.active = !PoisonManager.Instance.CheckInPoison(PlayerController.Instance.node.getWorldPosition());
    }

    _CheckKill() {
        let data = GameDataManager.Instance.getArrayData("TaskRequires");
        data[1]++;
        GameDataManager.Instance.setArrayData("TaskRequires", data);
        InGameManager.Instance.endData[0]++;
        this.gamerLeft.children[0].getComponent(Label).string = `击倒：${InGameManager.Instance.endData[0]}`;
    }

    _CheckGamer() {
        InGameManager.Instance.allGamers--;
        this.gamerLeft.children[1].getComponent(Label).string = `存活：${InGameManager.Instance.allGamers}`;
        if (InGameManager.Instance.allGamers == 1) GameUI.Instance.Win();
    }

    AutoShoot() {
        this.isAuto = !this.isAuto;
        this.autoShoot.progress = this.isAuto ? 1 : 0;
        this.autoShoot.getComponent(Sprite).color = color(255, 255, this.isAuto ? 0 : 255);
        this.autoLabel.string = this.isAuto ? "自动开火" : "手动开火";
        if (!this.isAuto && PlayerController.Instance.animationController.getValue("IsShoot")) PlayerController.Instance.ShootEnd();
    }

    Parachute() {
        this.parachuteBtn.active = false;
        this.parachute.active = true;
        this.rotatePanel.active = true;
        this.joyRect.active = true;
        let player = PlayerController.Instance.node;
        let pos = player.getWorldPosition();
        pos.y -= 2;
        player.setWorldPosition(pos);
        this.playerCamera.node.setPosition(v3(0, 0, 10));
        InGameManager.Instance.InitGamers();
    }

    Land() {
        this.parachute.active = false;
        this.btns.active = true;
        this.pack.active = true;
        this.frontSight.active = true;
        this._Init();
        tween(this.playerCamera.node)
            .to(1, {
                position: v3(0.5, 0, 5)
            })
            .start();
        let euler = PlayerController.Instance.node.children[0].eulerAngles.clone();
        euler.x = 0;
        PlayerController.Instance.node.children[0].setRotationFromEuler(euler);
        PlayerController.Instance.TestInit();
        PoisonManager.Instance.MoveNextPoison();
        InGameManager.Instance.ResetSpawn();
    }

}